#!/usr/bin/env python
"""
Acorn-SDR ('A Collection of Radio Nodes')
(c) Bob Cowdery (G3UKB) 2009

File: persist.py
Date: January 2009

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

The author can be reached by email at

bob@g3ukb.co.uk

================================================================================
Module Description:

The persistence layer.

"""

#-------------------------------------------------------------------------------
# System imports
import sys
import os
from time import sleep
import Ice, IceStorm

# Application imports
import persist
import ice_helpers

# Import the Ice interface definitions
import AcornLifeCycle
import AcornPersist
import AcornRxUpdate

#===============================================================================
# Ice life-cycle events for the GUI
class LifeCycleI(AcornLifeCycle.LifeCycle):
    
    #---------------------------------------------------------------------------   
    def __init__(self, service):
        self.service = service
      
    #---------------------------------------------------------------------------
    def start(self, current=None):
        pass
     
    #---------------------------------------------------------------------------   
    def stop(self, current=None):
        persist.save()
    
    #---------------------------------------------------------------------------    
    def terminate(self, current=None):
        persist.save()
        self.service.terminate()
        
#===============================================================================
# Ice receiver for the persist requests
class PersistI(AcornPersist.Persist):
    
    #---------------------------------------------------------------------------
    def __init__(self, updater, service):
        self.service = service
        self.updater = updater
        
    #---------------------------------------------------------------------------   
    def get(self, category, key, radio=0, current=None):
        val = persist.get(category, key, radio)
        if isinstance(val, int):
            discriminator = AcornPersist.MemberInt(val)
        elif isinstance(val, float):
            discriminator = AcornPersist.MemberFloat(val)
        elif isinstance(val, str):
            discriminator = AcornPersist.MemberString(val)
        else:
            discriminator = AcornPersist.MemberString('')
        return discriminator
        
    #---------------------------------------------------------------------------   
    def put(self, category, key, val, radio=0, current=None):
        
        discriminator = None
        if isinstance(val, AcornPersist.MemberInt):
            discriminator = val.i
        elif isinstance(val, AcornPersist.MemberFloat):
            discriminator = val.f
        elif isinstance(val, AcornPersist.MemberString):
            discriminator = val.s
            
        persist.put(category, key, discriminator, radio)
        # Tell who ever is interested we had an update
        if category == 'Profile':
            self.updater.configUpdate(key)
    
    #---------------------------------------------------------------------------   
    def getProfiles(self, current=None):
        return persist.get_profiles()
    
    #---------------------------------------------------------------------------   
    def setProfile(self, profile, current=None):    
        persist.set_profile(profile)
        
    #---------------------------------------------------------------------------   
    def getProfile(self, current=None):    
        return persist.get_profile()       
    
    #---------------------------------------------------------------------------   
    def save(self, current=None):
        persist.save()
    
#===============================================================================
class PersistService(Ice.Application):
    
    def __init__(self):
        self.close = False
    
    #---------------------------------------------------------------------------
    # Run the app
    def run(self, args):
        global glogger
       
        #-----------------------------------------------------------------------
        # Event names used here
        subscribe_to_lc = 'life_cycle_events'
        publish_to_rx_config = 'rx_config_events'
        
        #-----------------------------------------------------------------------
        # This is the same for both publishers and subscribers
        # Get the IceStorm topic manager interface
        manager = ice_helpers.get_topic_manager('Persist', self.communicator)
    
        # Retrieve the subscriber topic
        life_cycle_topic = ice_helpers.get_topic('Persist', manager, subscribe_to_lc)
        
        # Retrieve the publisher topic
        publisher_topic = ice_helpers.get_topic('DSP Service', manager, publish_to_rx_config)
        
        #-----------------------------------------------------------------------
        # Publisher side
        # Get the topic's publisher object, and create an update proxy
        publisher = publisher_topic.getPublisher();
        publisher = publisher.ice_oneway();        
        rx_config_publisher = AcornRxUpdate.RxConfigPrx.uncheckedCast(publisher)
        
        #-----------------------------------------------------------------------
        # Subscriber side
        # Create an adapter for the subscribers   
        adapter = self.communicator().createObjectAdapter("LifeCycle.Subscriber")
        subId = Ice.Identity()
        subId.name = Ice.generateUUID()        
        # Add the update interface
        subscriber = adapter.add(LifeCycleI(self), subId)
        # Subscribe to the topic - set up proxy
        ice_helpers.subscribe('Persist', life_cycle_topic, subscriber, id)
        # Now we can receive callbacks   
        adapter.activate()
        
        #-----------------------------------------------------------------------
        # Two way persist interface
        persist_adapter = self.communicator().createObjectAdapter("Persist")
        persist_adapter.add(PersistI(rx_config_publisher, self), self.communicator().stringToIdentity("persist"))        
        # Now we can receive callbacks for persistence 
        persist_adapter.activate()
        
        print 'Acorn-SDR (Persist Service) running..'
        
        #-----------------------------------------------------------------------
        # Wait for closedown
        while not self.close:
            # Idle loop for doing any other work
            sleep(1)

        # Unsubscribe all subscribed objects.
        # Causes an error
        #life_cycle_topic.unsubscribe(subscriber)
    
    #---------------------------------------------------------------------------
    # Terminate
    def terminate(self):
        self.close = True
        
#===============================================================================
#===============================================================================
# Start from the command line
if __name__ == "__main__":
  global glogger
   
  app = PersistService()
  app.main(sys.argv, sys.argv[1])
  
  # Announce we are going 
  print 'Acorn-SDR (Persist Service) closing..'
